package cn.lingyangwl.agile.pay.common.service.impl;

import cn.lingyangwl.agile.pay.common.assembly.*;
import cn.lingyangwl.agile.pay.common.mapper.*;
import cn.lingyangwl.agile.pay.common.service.*;
import cn.lingyangwl.agile.pay.model.entity.*;
import cn.lingyangwl.agile.pay.model.rqrs.*;
import cn.lingyangwl.agile.pay.pay.channel.*;
import cn.lingyangwl.agile.pay.pay.model.bo.*;
import cn.lingyangwl.agile.pay.pay.model.rqrs.bill.*;
import cn.lingyangwl.agile.pay.pay.service.*;
import cn.lingyangwl.framework.data.mate.annotations.*;
import cn.lingyangwl.framework.mybatis.plus.utils.*;
import cn.lingyangwl.framework.tool.core.*;
import cn.lingyangwl.framework.tool.core.exception.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 账单下载
 *
 * @author shenguangyang
 */
@Slf4j
@Service
public class BillServiceImpl extends ServiceImpl<BillDownloadMapper, BillDownload>
        implements BillService {

    @Resource
    private BillDownloadAssembly billDownloadAssembly;

    @Resource
    private ConfigContextQueryService configContextQueryService;

    /**
     * 分页查询 账单下载
     *
     * @return 返回分页数据
     */
    @Override
    @FieldBindHandle
    public IPage<BillDownloadRS> pageBillDownload(BillDownloadQueryReq req) {
        LocalDateTime beginTime = req.getBeginLocalDateTime();
        LocalDateTime endTime = req.getEndLocalDateTime();

        LambdaQueryWrapper<BillDownload> queryWrapper = BillDownload.lqw()
                .eq(StringUtils.isNotEmpty(req.getAppId()), BillDownload::getAppId, req.getAppId())
                .eq(StringUtils.isNotEmpty(req.getIfCode()), BillDownload::getIfCode, req.getIfCode())
                .eq(StringUtils.isNotEmpty(req.getBillType()), BillDownload::getBillType, req.getBillType())
                .eq(StringUtils.isNotEmpty(req.getMchNo()), BillDownload::getMchNo, req.getMchNo())
                .eq(Objects.nonNull(req.getCreatedAt()), BillDownload::getCreatedAt, req.getCreatedAt())
                .ge(Objects.nonNull(beginTime), BillDownload::getCreatedAt, beginTime)
                .le(Objects.nonNull(endTime), BillDownload::getCreatedAt, endTime)
                .orderByDesc(BillDownload::getCreatedAt);
        IPage<BillDownload> pageData = this.page(PageUtil.to(req), queryWrapper);
        List<BillDownloadRS> respData = pageData.getRecords().stream()
                .map(billDownloadAssembly::toBillDownloadResp)
                .collect(Collectors.toList());
        Page<BillDownloadRS> resp = new Page<>(pageData.getCurrent(), pageData.getSize(), pageData.getTotal());
        resp.setRecords(respData);
        return resp;
    }


    /**
     * 根据主键查询 账单下载
     *
     * @param id 主键
     * @return 返回记录，没有返回null
     */
    @Override
    @FieldBindHandle
    public BillDownloadRS getBillDownload(Long id) {
        BillDownload po = this.getById(id);
        return billDownloadAssembly.toBillDownloadResp(po);
    }

    /**
     * 通过id删除 账单下载
     *
     * @param id 删除的主键
     * @return 返回影响行数
     */
    @Override
    public boolean deleteBillDownload(Long id) {
        return this.removeById(id);
    }

    /**
     * 通过ids删除 账单下载
     *
     * @param ids 删除的主键
     * @return 返回影响行数
     */
    @Override
    public boolean batchDeleteBillDownload(List<Long> ids) {
        return this.removeByIds(ids);
    }

    @Override
    public void downloadBill(BillQueryRQ rq) throws Exception {
        IBillService billService = AbstractBillService.getService(rq.getIfCode());
        if (Objects.isNull(billService)) {
            throw new BizException("未实现当前支付接口的账单下载功能");
        }
        MchAppConfigContext mchAppConfigContext = configContextQueryService.queryMchInfoAndAppInfo(rq.getMchNo(), rq.getAppId());
        if (Objects.isNull(mchAppConfigContext)) {
            throw new BizException("商户号或者商户应用不存在/匹配");
        }

        billService.exportTradeBill(rq, mchAppConfigContext);
        // 记录下载日志
        BillDownload billDownload = BillDownload.builder()
                .billType("trade").ifCode(rq.getIfCode()).mchNo(rq.getMchNo())
                .appId(rq.getAppId())
                .build();
        this.save(billDownload);
    }
}
